/**
 * 实现一个函数，将一个对象数组按照group分组，返回一个新的对象，对象的key为group的值，value为group相同的对象组成的数组。
 * 如果group的值不存在，将该对象放到unknown数组中。
 * 如果group的值为undefined，将该对象放到unknown数组中。
 * @param {Array} arr - 需要分组的对象数组
  [
    {name: 'a', value: 1, group: 'group1'},
    {name: 'b', value: 2, group: 'group1'},
    {name: 'c', value: 3, group: 'group2'},
    {name: 'd', value: 4, group: 'group3'},
    {name: 'e', value: 5},
  ]
  @returns {Object} - 分组后的对象
  res = {
    group1: [
      {name: 'a', value: 1, group: 'group1'},
      {name: 'b', value: 2, group: 'group1'},
    ],
    group2: [
      {name: 'c', value: 3, group: 'group2'},
    ],
    group3: [
      {name: 'd', value: 4, group: 'group3'},
    ],
    unknown: [
      {name: 'e', value:5},
    ]
  }
 */
function transformObjToArr(arr) {
  if (!Array.isArray(arr)) {
    return arr;
  }
  return arr.reduce((acc, cur) => {
    const key = cur.group || 'unknown';
    if (!acc[key]) {
      acc[key] = [];
    }
    acc[key].push(cur);
    return acc;
  }, {});
  // const obj = {};
  // arr.forEach(i => {
  //   const key = i.group || 'unknown';
  //   if (!obj[key]) {
  //     obj[key] = [];
  //   }
  //   const { group, ...rest } = i;
  //   obj[key].push(rest);
  // });
  // return obj;
}

const params = [
  { name: 'a', value: 1, group: 'group1' },
  { name: 'b', value: 2, group: 'group1' },
  { name: 'c', value: 3, group: 'group2' },
  { name: 'd', value: 4, group: 'group3' },
  { name: 'e', value: 5 }
];
console.log(transformObjToArr(params));

function isObject(obj) {
  return typeof obj === 'object' && obj !== null;
}
function isEuqal(val1, val2) {
  // 只要有一个不是对象，就不必遍历比较
  if (!isObject(val1) || !isObject(val2)) {
    // return i === item;
    return Object.is(val1, val2);
  }
  const keys1 = Object.keys(val1);
  const keys2 = Object.keys(val2);
  if (keys1.length !== keys2.length) {
    return false;
  }
  for (const key of keys1) {
    if (!keys2.includes(key)) {
      return false;
    }
    if (!isEuqal(val1[key], val2[key])) {
      return false;
    }
  }
  return true;
}
/**对象数组去重
 * 该函数用于对数组中的元素进行去重操作，支持数组中包含对象的情况。
 * [{name:'a',age:1},{name:'b',age:2},{name:'a',age:1}]
 * @param {Array} arr - 需要去重的数组，数组元素可以是基本数据类型或对象。
 * @returns {Array} - 去重后的数组，保留了原数组中元素的顺序。
 */
function qc(arr) {
  const res = [];
  for (const item of arr) {
    if (!res.some(i => isEuqal(i, item))) {
      res.push(item);
    }
    // let isFind = false;
    // for (const i of res) {
    //   if (isEuqal(i, item)) {
    //     isFind = true;
    //     break;
    //   }
    // }
    // if (!isFind) {
    //   res.push(item);
    // }
  }
  return res;
}

const qcarr = [[], [], { name: 'a', age: 1 }, { name: 'b', age: 2 }, { name: 'a', age: 1 }];
console.log(qc(qcarr));

/**
 * 数组拍平
 * 将嵌套的数组转换为一维数组
 * @param {Array} arr - 需要拍平的数组，可以包含多层嵌套
 * @returns {Array} - 拍平后的一维数组
 */
const flatArr = arr => {
  return arr.reduce((acc, pre) => {
    // acc是累积器，用于存储拍平后的数组，初始值为空数组
    // pre表示当前正在处理的元素
    if (Array.isArray(pre)) {
      acc = [...acc, ...flatArr(pre)];
    } else {
      acc = [...acc, pre];
    }
    return acc;
  }, []);
};

const arr = [1, [1, 2]];
flatArr(arr);

/**
 * 将给定的字符串反转
 * 如果输入不是字符串类型，则直接返回该输入
 *
 * @param {any} str - 需要被反转的字符串，如果不是字符串将原样返回
 * @returns {string | any} - 反转后的字符串，或原样输入
 */
const fzstr = str => {
  if (typeof str !== 'string') {
    return str;
  }
  return [...str].reduce((acc, cur) => {
    return `${cur}${acc}`;
  }, '');
};
console.log(fzstr('123'));
